7セグ表示周波数カウンター
7セグメンントLED表示の周波数カウンターを PICを利用して作製することを試みた。 そのために、PICの タイマー機能と 割り込みの手法を用いた。
1. 調整可能な基準信号発生器の作成:
TTL ICで作製した5桁周波数カウンターの10進基準信号発生器の代わりに、PIC16F628Aによる ゲートタイムが調整可能な基準信号発生器を設け、スイッチの切り替えによって 約0.1S、0.01S、0.001S間隔のダブル・クロックパルスによってTTL ICカウンター基板のラッチ、クリアを行い、各ゲートタイムごとに正確に周波数をカウントするように改造した。
RES(リセット)端子に0.047μFを入れることにより、ダイナミックドライブの表示ずれを解消した。また、オープン時の
SWが完全に 0になるためには、(プルアップをしていないにもかかわらず、PICはC−MOSなので、)100kΩでアースに落とす必要がある。
また、プログラムのタイマ1の初期値を微調整しやすいように、PIC kit
端子を設けた。
プログラムは、メインでは何もせず while(1)で永遠に繰り返しているだけで、タイマ1のオーバーフローによって 関数 entry に飛ぶ。(interrupt は割り込み関数の頭に付ける) タイマ1の割り込みが発生したなら、SWの3つの状態に応じて、クロックパルスとリセットパルスを出力した後、それぞれのタイマ1の初期値を再設定してメイン関数に戻すことによってゲート・タイムを決める。(タイマ1は、2バイト=65535まで設定可能で、これが分解能になる。TMR1H(上位ビット
256) と TMR1L(下位ビット 256)に分けて表示する。) 挿入された
NOP( )は、タイマ1の最小分解能とほぼ同じだったので、省略してタイマ1のみで決めても良い。
SW1(約0.1S)の場合、タイマ1の最大時間を超えるので、約0.01Sを10回繰り返した。
また、ダイナミック・ドライブの駆動用パルスには、タイマ2の CCPモジュールによる
PWM信号を用いた。(約1kHz、デューティー比約50%、5V方形波)
結果は、タイマ1とタイマ2の干渉など起こらず、安定していて滑らかな動きであり、測定精度もレンジ切替により 5〜6桁まではOKだった。(周波数 約50MHzまで正確、ただし、30MHzを超えると測定の閾値が高くなるので、実用範囲は 30数MHz程度。水晶発振子(10.000MHz)の精度は高くないが、安定度は充分ある。)
・・・・・ 4.000MHz、14.31818MHz、48.000MHzのそれぞれのクリスタルオシレータによる測定結果では、 レンジ1: 4.000、
14.318、 48.000、 レンジ2: 4.0000、 4.3182、8.0005、 レンジ3: 99995、
31819、99986 のようになった。これ以上は、TMR1Lの数値1つを増減すると
より大きくずれるので、この辺が調整の限界となる。
● ソース:
* TTL IC方式の周波数カウンターは非常に堅牢で、作ってから3年にもなるが問題なく動いている。 その昔、周波数カウンターの調整は、各レンジごとに決められた周波数に水晶を作り、キャップを外して水晶振動子に”赤チン”を塗って微調整したそうである。
2. 全PIC化の試み:
工作は比較的簡単で、ダイナミックドライブのため多くの出力ピンが必要なので、40pinの
PIC16F877Aを用いた。
高周波の計数(タイマ0のクロックソース(T0CKI: RA4、30MHzまで)から入力。とりあえず、2×50=100ごとに次の10進ソフトカウンタへ。何進であっても、最大2バイト以下ならば後の演算で修正できる。)、ゲートタイムごとの割込み(タイマ1のオーバーフロー)、7セグメント表示器のダイナミックドライブ(タイマ1とN回に1回同期させる)
の3つを、一つのPICで行なうという試みだったが、結論から言うと、無理があった。
問題点の1つ目は、計測した数値の表示が、 1〜3桁目の低位桁で 20回に1回くらい低い値と高い値を示すことであり、ゲートタイムを1(S)にしても3〜4桁の精度しか出ないことである。
これは、メインでの計測値をタイマ1の割込みでキャプチャーするとき、メインのループのどこで割り込みが発生するかによる。
また、割込みで、ダイナミックドライブのN回(N=2500)に1回ずつデータを更新するので、タイマ1の初期値設定による分解能が悪くなる。
さらに、割り込み関数へ移行すると、タイマ0は無関係にそのまま動いているが、上位のソフトカウンター(プログラム上のカウンター)はすべて止まってしまう。このため、
・ 割り込み直後、b=TMR0 と置いて固定し、割込みから抜ける直前に、TMR0=b
として戻し、そこから再スタートする。
・ T0CKI(RA4)pin に RA5 pinを結合し、RA5を出力用(0)にすることで強制的にT0CKIからの入力を遮断する。
・ 外部のゲート(74LS00など)を使って入力を遮断する。
などの方法を試みたが、あまり効果が無かった。
この周期的な誤差を修正するプログラムを追加する必要がある。
問題点の2つ目は、捉えた数値データを演算処理する際、若干の時間がかかるため、ダイナミックドライブの表示にゲートタイムごとのちらつきが出ることである。ゲートタイムを1S程度にして目立たないようにすることで解決した。(時計のように1秒ごとに全体が点滅するが、目障りといえば目障り)
* すべて一つのPICでコンパクトに行なうには、LED表示のダイナミックドライブは無理であり、ダイナミックドライブ機能が内蔵されている LCD表示器を用いるべきである。 LCD表示では、割り込み関数を用いることも無く 普通の関数を呼び出す形で、精度が高く、割込みどおしの干渉も起こらない。
● ソース: font7s.h :(Header files に貼る)
3. TTLカウント基板のPICによる制御:
PICのメインプログラムによる計数を止め、TTL IC によるカウント基板(3桁×2枚=6桁分)を作製し、これをPIC基板から制御する(CK、RES)と同時に、カウント基板からのBCD信号(4ビット:
A、B、C、D)を入力し、数値化、7セグFONT化して、このメインの方で
ダイナミックドライブする。 タイマ1による割込みでは、ゲートタイムによるCK、RES出力のみを行なう。 カウント基板へのダイナミックドライブ用
Q1〜Q6出力は、sel [ ](RB0〜5)から配線した。(Q6:RB0、
Q5:RB1、・・・、Q1:RB5)
カウント基板は 74LS90を用いて10進カウントしたが、93などによる16進カウントをすればICを節約できる。(5セットで7桁)
ここで、TTLレベルと C−MOSレベル(PIC)とのマッチングの問題があり、TTLのBCD出力には1MΩ〜1.65MΩ程度の高抵抗でアースに落とす必要があった。(カウンタ基板2枚について抵抗1ヶ所。
スイッチング・ダイオードに並列する抵抗群は不要。 TTLの入力スレシホールドレベル約3Vに対し、C−MOS(PIC)は
4V近く必要。) 1.と違って、CKからコンデンサーで落とす必要はなかった。
また、ブランク回路は特に組まず、メインプログラムで行なう。
表示に用いた 青色超高輝度7セグLED(OSL10561−LB、カソードコモン)はきわめて輝度が高いので、470Ωの抵抗を通して駆動した。
基板を3枚重ねて、PS−2のケースに楽に収まった。電源は5Vアダプター(1A)を使用。(消費電力:
5V、150mA程度)
こちらの方は、1.と同様に、ちらつきも無く、正確に測定できた。(5〜6桁) ただし、20MHz以上の比較的高周波側や、変動する周波数源(LC発振など)では、周期的に不安定な表示をすることがある。
したがって、1/100のプリスケーラー(74AC00 + 74AC390、
1/10は高調波が多くて使えない)を付けて、高周波専用(プリスケーラー入力
180MHzmaxで、カウンターでの直接の計測は1.8MHz以下)にした方が良いと思われる。
● ソース: font7s.h :(Header files に貼る)